package com.jyw.business.ast.service.impl;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import com.alibaba.excel.EasyExcel;
import com.jyw.business.ast.domain.AstConsumableRecord;
import com.jyw.business.ast.domain.dto.web.*;
import com.jyw.business.ast.domain.vo.web.AstConsumableClaimVo;
import com.jyw.business.ast.domain.vo.web.AstConsumableDetailVo;
import com.jyw.business.ast.domain.vo.web.AstConsumablePageVo;
import com.jyw.business.ast.domain.vo.web.AstConsumableReserveRecordVo;
import com.jyw.business.ast.service.IAstConsumableClaimService;
import com.jyw.business.ast.service.IAstConsumableRecordService;
import com.jyw.common.exception.ServiceException;
import com.jyw.common.utils.DateUtils;
import com.jyw.system.utils.ConversionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.jyw.business.ast.mapper.AstConsumableMapper;
import com.jyw.business.ast.domain.AstConsumable;
import com.jyw.business.ast.service.IAstConsumableService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;

/**
 * 资产-耗材信息Service业务层处理
 * 
 * @author system
 * @date 2023-10-24
 */
@Service
@Slf4j
public class AstConsumableServiceImpl extends ServiceImpl<AstConsumableMapper,AstConsumable> implements IAstConsumableService
{
    @Resource
    private AstConsumableMapper astConsumableMapper;

    @Resource
    private IAstConsumableClaimService claimService;

    @Resource
    private IAstConsumableRecordService recordService;

    /**
     * 查询资产-耗材信息
     * 
     * @param id 资产-耗材信息主键
     * @return 资产-耗材信息
     */
    @Override
    public AstConsumable selectAstConsumableById(Long id)
    {
        return astConsumableMapper.selectAstConsumableById(id);
    }

    /**
     * 查询资产-耗材信息列表
     * 
     * @param astConsumable 资产-耗材信息
     * @return 资产-耗材信息
     */
    @Override
    public List<AstConsumable> selectAstConsumableList(AstConsumable astConsumable)
    {
        return astConsumableMapper.selectAstConsumableList(astConsumable);
    }

    /**
     * 新增资产-耗材信息
     * 
     * @param astConsumable 资产-耗材信息
     * @return 结果
     */
    @Override
    public int insertAstConsumable(AstConsumable astConsumable)
    {
        astConsumable.setCreateTime(DateUtils.getNowDate());
        return astConsumableMapper.insertAstConsumable(astConsumable);
    }

    /**
     * 修改资产-耗材信息
     * 
     * @param astConsumable 资产-耗材信息
     * @return 结果
     */
    @Override
    public int updateAstConsumable(AstConsumable astConsumable)
    {
        return astConsumableMapper.updateAstConsumable(astConsumable);
    }

    /**
     * 批量删除资产-耗材信息
     * 
     * @param ids 需要删除的资产-耗材信息主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteAstConsumableByIds(Long[] ids)
    {
        return lambdaUpdate()
                .in(AstConsumable::getId,ids)
                .set(AstConsumable::getRecordState,0)
                .update() ? 1 : 0;
    }

    /**
     * 删除资产-耗材信息信息
     * 
     * @param id 资产-耗材信息主键
     * @return 结果
     */
    @Override
    public int deleteAstConsumableById(Long id)
    {
        return astConsumableMapper.deleteAstConsumableById(id);
    }

    @Override
    public List<AstConsumablePageVo> consumablePage(AstConsumablePageDto dto) {
        List<AstConsumablePageVo> astConsumablePageVos = astConsumableMapper.consumablePage(dto);
        return ConversionUtil.conversionList(astConsumablePageVos,AstConsumablePageVo.class);
    }

    @Override
    public AstConsumableDetailVo consumableDetail(Long id) {
        //查询耗材信息
        AstConsumable consumable = getById(id);
        //查询申领记录
        List<AstConsumableClaimVo> claims = claimService.consumableClaim(id);
        //查询入库记录
        List<AstConsumableReserveRecordVo> warehouse = recordService.reserveRecord(id, "2");
        //查询出库记录
        List<AstConsumableReserveRecordVo> outOfWarehouse = recordService.reserveRecord(id, "3");
        return new AstConsumableDetailVo(consumable,claims,warehouse,outOfWarehouse);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void consumableSign(AstConsumableSignDto dto) {
        AstConsumable consumable = dto.buildAstConsumable();
        save(consumable);
        log.info("耗材登记:{}",consumable);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(AstConsumableEditDto dto) {
        AstConsumable consumable = dto.buildAstConsumable();
        updateById(consumable);
        log.info("耗材编辑:{}",consumable);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void warehouse(AstConsumableReverseDto dto) {
        //记录
        List<AstConsumableRecord> recordList = dto.buildRecord("2");
        recordService.saveBatch(recordList);
        //修改实际库存
        recordList.forEach(data->{
            astConsumableMapper.updateReverse(data);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void outOfWarehouse(AstConsumableReverseDto dto) {
        List<AstConsumableRecord> recordList = dto.buildRecord("3");
        recordService.saveBatch(recordList);
        //修改实际库存
        recordList.forEach(data->{
            data.setQuantity(-data.getQuantity());
            astConsumableMapper.updateReverse(data);
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void frostReserve(List<ReserveDto> reverseList) {
        reverseList.forEach(data->{
            astConsumableMapper.frostReserve(data);
        });
    }

    @Override
    public void thawReserve(AstConsumableRecord data) {
        astConsumableMapper.thawReserve(data);
    }

    @Override
    public void claimPass(AstConsumableRecord data) {
        astConsumableMapper.claimPass(data);
    }

    @Override
    public void importData(MultipartFile file) {
        try {
            //读取Excel
            List<AstConsumableImportDto> list = EasyExcel
                    //文件流读取
                    .read(file.getInputStream())
                    //指向对象
                    .head(AstConsumableImportDto.class)
                    //指定从多少行开始读取
                    .headRowNumber(2)
                    //指定sheet
                    .sheet()
                    //同步读取
                    .doReadSync();

            log.info("耗材导入,解析的数据是:{}",list);
            List<AstConsumable> consumableList = list.stream().filter(data ->
                    //过滤名称,分类,使用单位为空的数据
                    !(ObjectUtils.isEmpty(data.getName())
                            ||
                            ObjectUtils.isEmpty(data.getType())
                            || ObjectUtils.isEmpty(data.getUnit()))
            ).map(data -> {
                AstConsumable consumable = data.buildConsumable();
                return consumable;
            }).collect(Collectors.toList());
            saveBatch(consumableList);
        } catch (Exception e) {
            log.error("耗材导入报错",e);
            throw new ServiceException("解析导入模板失败");
        }
    }
}
